05-09 17:01:13.547: I/ActivityManager(3003): START u0 {act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=https://www.baidu.com cmp=android/com.android.internal.app.ResolverActivity} from pid 5222
05-09 17:01:13.587: I/ActivityManager(3003): Start proc system:ui for activity android/com.android.internal.app.ResolverActivity: pid=15544 uid=1000 gids={41000, 3002, 3001, 3003, 1028, 1015, 1023, 1021, 3004, 3005, 1000, 3009, 1010}
05-09 17:01:14.557: I/ActivityManager(3003): Displayed android/com.android.internal.app.ResolverActivity: +975ms
从ActivityManger输出Log可以知道是ResolverActivity处理app选择。
android\frameworks\base\core\java\com\android\internal\app\ResolverActivity.java
protected void onCreate(Bundle savedInstanceState) {
// Use a specialized prompt when we're handling the 'Home' app startActivity()
final int titleResource;
final Intent intent = makeMyIntent();
final Set categories = intent.getCategories();
if (Intent.ACTION_MAIN.equals(intent.getAction())
&& categories != null
&& categories.size() == 1
&& categories.contains(Intent.CATEGORY_HOME)) {
titleResource = com.android.internal.R.string.whichHomeApplication;//选择主屏幕应用
} else {
titleResource = com.android.internal.R.string.whichApplication;//选择要使用的应用:
}
onCreate(savedInstanceState, intent, getResources().getText(titleResource),
null, null, true);
}
protected void onCreate(Bundle savedInstanceState, Intent intent,
CharSequence title, Intent[] initialIntents, List rList,
boolean alwaysUseOption) {
setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert);
super.onCreate(savedInstanceState);
try {
mLaunchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
getActivityToken());
} catch (RemoteException e) {
mLaunchedFromUid = -1;
}
mPm = getPackageManager();
mAlwaysUseOption = alwaysUseOption;
mMaxColumns = getResources().getInteger(R.integer.config_maxResolverActivityColumns);
AlertController.AlertParams ap = mAlertParams;
ap.mTitle = title;
mPackageMonitor.register(this, getMainLooper(), false);
mRegistered = true;
final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
mIconDpi = am.getLauncherLargeIconDensity();
mIconSize = am.getLauncherLargeIconSize();
mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList, mLaunchedFromUid);//获取APP列表
int count = mAdapter.getCount();
if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
// Gulp!
finish();
return;
} else if (count > 1) {
ap.mView = getLayoutInflater().inflate(R.layout.resolver_list, null);
mListView = (ListView) ap.mView.findViewById(R.id.resolver_list);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(this);
mListView.setOnItemLongClickListener(new ItemLongClickListener());
if (alwaysUseOption) {
mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
} else if (count == 1) {
startActivity(mAdapter.intentForPosition(0));
mPackageMonitor.unregister();
mRegistered = false;
finish();
return;
} else {
ap.mMessage = getResources().getText(R.string.noApplications);
}
setupAlert();
if (alwaysUseOption) {
final ViewGroup buttonLayout = (ViewGroup) findViewById(R.id.button_bar);
if (buttonLayout != null) {
buttonLayout.setVisibility(View.VISIBLE);
mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
} else {
mAlwaysUseOption = false;
}
// Set the initial highlight if there was a preferred or last used choice
final int initialHighlight = mAdapter.getInitialHighlight();
if (initialHighlight >= 0) {
mListView.setItemChecked(initialHighlight, true);
onItemClick(null, null, initialHighlight, 0); // Other entries are not used
}
}
}
点击“始终”按钮,设置默认程序
public void onButtonClick(View v) {
final int id = v.getId();
startSelected(mListView.getCheckedItemPosition(), id == R.id.button_always);
dismiss();
}
void startSelected(int which, boolean always) {
if (isFinishing()) {
return;
}
ResolveInfo ri = mAdapter.resolveInfoForPosition(which);
Intent intent = mAdapter.intentForPosition(which);
onIntentSelected(ri, intent, always);
finish();
}
protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
if (mAlwaysUseOption && mAdapter.mOrigResolveList != null) {
// Build a reasonable intent filter, based on what matched.
IntentFilter filter = new IntentFilter();
if (intent.getAction() != null) {
filter.addAction(intent.getAction());
}
Set categories = intent.getCategories();
if (categories != null) {
for (String cat : categories) {
filter.addCategory(cat);
}
}
filter.addCategory(Intent.CATEGORY_DEFAULT);
int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
Uri data = intent.getData();
if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
String mimeType = intent.resolveType(this);
if (mimeType != null) {
try {
filter.addDataType(mimeType);
} catch (IntentFilter.MalformedMimeTypeException e) {
Log.w("ResolverActivity", e);
filter = null;
}
}
}
if (data != null && data.getScheme() != null) {
// We need the data specification if there was no type,
// OR if the scheme is not one of our magical "file:"
// or "content:" schemes (see IntentFilter for the reason).
if (cat != IntentFilter.MATCH_CATEGORY_TYPE
|| (!"file".equals(data.getScheme())
&& !"content".equals(data.getScheme()))) {//注意这里排除了"file://", "content://"
filter.addDataScheme(data.getScheme());
// Look through the resolved filter to determine which part
// of it matched the original Intent.
Iterator pIt = ri.filter.schemeSpecificPartsIterator();
if (pIt != null) {
String ssp = data.getSchemeSpecificPart();
while (ssp != null && pIt.hasNext()) {
PatternMatcher p = pIt.next();
if (p.match(ssp)) {
filter.addDataSchemeSpecificPart(p.getPath(), p.getType());
break;
}
}
}
Iterator aIt = ri.filter.authoritiesIterator();
if (aIt != null) {
while (aIt.hasNext()) {
IntentFilter.AuthorityEntry a = aIt.next();
if (a.match(data) >= 0) {
int port = a.getPort();
filter.addDataAuthority(a.getHost(), port >= 0 ? Integer.toString(port) : null);
break;
}
}
}
pIt = ri.filter.pathsIterator();
if (pIt != null) {
String path = data.getPath();
while (path != null && pIt.hasNext()) {
PatternMatcher p = pIt.next();
if (p.match(path)) {
filter.addDataPath(p.getPath(), p.getType());
break;
}
}
}
}
}
if (filter != null) {
final int N = mAdapter.mOrigResolveList.size();
ComponentName[] set = new ComponentName[N];
int bestMatch = 0;
for (int i=0; i bestMatch) bestMatch = r.match;
}
if (alwaysCheck) {
getPackageManager().addPreferredActivity(filter, bestMatch, set, intent.getComponent());//设置默认
} else {
try {
AppGlobals.getPackageManager().setLastChosenActivity(intent,
intent.resolveTypeIfNeeded(getContentResolver()),
PackageManager.MATCH_DEFAULT_ONLY,
filter, bestMatch, intent.getComponent());
} catch (RemoteException re) {
Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
}
}
}
}
if (intent != null) {
startActivity(intent);
}
}
当系统存在多个launcher时,若没有设置默认launcher,开机启动后会弹出提示框,罗列所有launcher,用户选择并设置了默认launcher后,按home键以及以后重启都会进入默认的launcher。
现在,我希望系统能直接就进入我设定的launcher而不是弹出框后选择然后设置
网上大部分的做法就是修改
1
packages/apps/Provision/src/com/android/DefaultActivity.java
和
1
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java
两个文件,给个相对比较好看一点的链接http://blog.csdn.net/z_guijin/article/details/8964890
我按照这个做不能达到预期的效果,
/添加内容
后期修改包名,发现开机自启动出现问题,然后弄了两天,终于差不多弄清楚了。果然,欠下的债迟早得还!
其实修改DefaultActivity.java就能够完成开机自启动,只是当时我的程序有问题,所以没有达到预期效果
当然下面修改ActivityManagerService.java也能完成开机自启动
这两者的区别在于 DefaultActivity.java只是在第一次启动时执行,如果修改了默认launcher后不可恢复
ActivityManagerService.java在每次启动时执行,每次都默认启动设定的launcher,当然,如果设定的launcher存在的话,设置其他的launcher为默认会无效,因为重新启动时setDefaultLauncher()会将当前默认launcher清除。只有在卸载了设定默认启动的launcher后才能设置其他launcher为默认启动.
//
修改多次搜索关键字,得到另一篇文章,大致看了下,感觉不会有效,但是已经绝望了就试了试,竟然解决了问题http://blog.csdn.net/jia4525036/article/details/18036765
这篇文章有借鉴之处,直接使用时会发现有些字段是上下文中没有的,故写下此文记录一下。
修改文件
1
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
添加一个方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
private
void
setDefaultLauncher() {
// get default component
String packageName =
"com.coship.factorytest"
;
//默认launcher包名
String className =
"com.coship.factorytest.MainActivity"
;
默认launcher入口
IPackageManager pm = ActivityThread.getPackageManager();
//判断指定的launcher是否存在
if
(hasApkInstalled(packageName)) {
Slog.i(TAG,
"defautl packageName = "
+ packageName +
", default className = "
+ className);
//清除当前默认launcher
ArrayList intentList =
new
ArrayList();
ArrayList cnList =
new
ArrayList();
mContext.getPackageManager().getPreferredActivities(intentList, cnList,
null
);
IntentFilter dhIF =
null
;
for
(
int
i =
0
; i |